/**
 * @ProjectName: go-learn-demo
 * @PackageName: _2_relation
 * @Description:
 * @Author: hy.bai
 * @Date: 2025-08-05 18:10
 */
package hasmanycreatetables

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"time"
)

var currentTimeStr = time.Now().Format(time.DateTime)

// 实现一对多的功能:创建两个关联的结构体
// 定义一对多功能是在多的一侧加外键。
// 定义用户结构体

type User struct {
	gorm.Model                 // 注意：gorm.Model是gorm提供的一个基础结构体，包括:ID,CreatedAt,UpdatedAt,DeletedAt四个属性
	Name         string        // 用户名
	MemberNumber string        `gorm:"size:64;index"` // 会员编号
	CreditCards  []*CreditCard `gorm:"foreignKey:UserRefer;references:MemberNumber"`
	// CreditCards属性是用于关联查询，不会在数据库中创建表字段。
}

// 定义信用卡结构体
type CreditCard struct {
	gorm.Model        // 注意：gorm.Model是gorm提供的一个基础结构体，包括:ID,CreatedAt,UpdatedAt,DeletedAt四个属性
	Number     string // 信用卡卡号
	UserRefer  string `gorm:"size:64;index"` // 用户结构体主键,这里是一对多的标志。即：User结构体的主键
	// 默认是结构体的名字 + id。当自己指定时，需要在一的一端的切片属性中通过"foreignKey"标签进行指定。即：gorm:"foreignKey:UserRefer"
}

// 注意：在gorm.Model结构体中,有"DeletedAt DeletedAt `gorm:"index"`"删除时间。即：删除操作变成了软删除。
// 软删除是：默认情况下，DeletedAt字段是为null的，删除之后即是填充了删除时间。所以：软删除操作就是把DeletedAt字段从null值设置为具体的删除时间。
// 默认在查询时，不会查询DeletedAt字段不为空的数据(deleted_at is null).

func TestHasManyCreateTable() {
	// 1.拼接URL地址
	dns := "root:root@tcp(127.0.0.1:3308)/test?charset=utf8mb4&parseTime=True&loc=Local"
	// parseTime是查询结果是否自动解析为时间类型,即：time.Time类型，对应的数据库中的类型是：datetime
	// loc是Mysql的时区设置
	// 2.定义gorm的配置,打印Sql日志
	gConfig := &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info),
		// DryRun: true, // 生成SQL语句, 不执行
	}
	db, err := gorm.Open(mysql.Open(dns), gConfig)
	if err != nil {
		panic(fmt.Sprintf("连接数据库失败,失败原因是:%s\n", err.Error()))
	} else {
		fmt.Println(db.Name()) // mysql:表示数据库连接成功
	}
	user := &User{}
	hasTable := db.Migrator().HasTable(user)
	fmt.Println("用户表示是否存在:", hasTable)
	userErr := db.Debug().Set("gorm:table_options", "COMMENT='用户信息表'").AutoMigrate(user)
	if userErr != nil {
		fmt.Printf("创建用户表失败,失败原因是:%s\n", userErr.Error())
		return
	}
	ccErr := db.Debug().Set("gorm:table_options", "COMMENT='信用卡信息表'").AutoMigrate(&CreditCard{})
	if ccErr != nil {
		fmt.Printf("创建信用卡表失败,失败原因是:%s\n", ccErr.Error())
		return
	}
	fmt.Printf("当前时间:%s, Mysql数据库相关操作执行完成~~~\n", currentTimeStr)
}
